﻿#include "temperaturehumiditysensor.h"
#include "3rdparty/includes/deviceio/ideviceio.h"
#include "model/deviceinstancemanager.h"

#include <common/common.h>

TemperatureHumiditySensor::TemperatureHumiditySensor(QThread *parent)
    : QThread {parent}
{
}

TemperatureHumiditySensor::~TemperatureHumiditySensor()
{
}
quint16 calculateCRC16(const QByteArray &data)
{
    quint16 crc = 0xFFFF;

    for (int i = 0; i < data.size(); ++i) {
        crc ^= static_cast<quint8>(data[i]);

        for (int j = 0; j < 8; ++j) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }

    return crc;
}

QByteArray buildRequestFrame()
{
    // 构建请求帧：地址码(0x01) + 功能码(0x03) + 起始地址(0x0000) + 寄存器数量(0x0002)
    QByteArray frame;
    frame.append((char)0x01); // 设备地址
    frame.append((char)0x03); // 功能码
    frame.append((char)0x00); // 起始地址高位
    frame.append((char)0x00); // 起始地址低位
    frame.append((char)0x00); // 寄存器数量高位
    frame.append((char)0x02); // 寄存器数量低位

    // 计算CRC16校验
    quint16 crc = calculateCRC16(frame);
    frame.append((char)(crc & 0xFF));        // CRC低位
    frame.append((char)((crc >> 8) & 0xFF)); // CRC高位
    return frame;
}

bool parseResponseFrame(const QByteArray &response,
                        double &temperature, double &humidity)
{
    if (response.size() < 7) { // 最小响应长度：地址(1) + 功能码(1) + 数据长度(1) + 数据(4) + CRC(2)
        // qWarning() << QString("响应数据长度不足: %1, data: ").arg(response.size()) << response.toHex();
        return false;
    }

    // 验证地址和功能码
    if (static_cast<quint8>(response[0]) != 0x01 || static_cast<quint8>(response[1]) != 0x03) {
        // qWarning() << "响应帧地址或功能码错误";
        return false;
    }

    quint8 dataLength = static_cast<quint8>(response[2]);
    if (dataLength != 0x04) {
        // qWarning() << QString("数据长度错误，期望4，实际%1").arg(dataLength);
        return false;
    }

    if (response.size() < 5 + dataLength) {
        // qWarning() << "响应数据不完整";
        return false;
    }

    // 验证CRC校验
    QByteArray crcData = response.left(response.size() - 2);
    quint16 receivedCRC = static_cast<quint8>(response[response.size() - 2]) | (static_cast<quint8>(response[response.size() - 1]) << 8);
    quint16 calculatedCRC = calculateCRC16(crcData);

    if (receivedCRC != calculatedCRC) {
        // qWarning() << "CRC校验失败";
        return false;
    }

    // 提取湿度数据 (字节3-4)
    quint16 humidityRaw = (static_cast<quint8>(response[3]) << 8) | static_cast<quint8>(response[4]);
    humidity = humidityRaw / 10.0; // 湿度值需要除以10

    // 提取温度数据 (字节5-6)
    quint16 tempRaw = (static_cast<quint8>(response[5]) << 8) | static_cast<quint8>(response[6]);
    qint16 signedTemp = static_cast<qint16>(tempRaw); // 转换为有符号整数
    temperature = signedTemp / 10.0;                  // 温度值需要除以10

    // qDebug() << "解析到的数据 - 温度:" << temperature << "°C, 湿度:" << humidity << "%RH";

    return true;
}

void TemperatureHumiditySensor::run()
{
    QString add = Utils::loadTemperatureHumiditySensorConfig();
    const QString dllPathIO = Utils::instance()->resolveDriverPathIO(DeviceInterfaceType::LAN);
    DeviceHandle<IDeviceIO> device = makeDeviceHandle<IDeviceIO>(dllPathIO);
    if (!device->connect(add)) {
        qWarning() << "Temperature Humidity Sensor connect failed! add:" << add;
        return;
    }
    double temperature, humidity;
    QByteArray resData;
    while (1) {
        resData.clear();
        device->write(buildRequestFrame());
        msleep(30);
        resData = device->read();
        //测试数据 01 03 04 02 92 FF 9B 5A 3D 温度-10.1 湿度：65.8%
        if (parseResponseFrame(resData, temperature, humidity))
            emit sig_updataData(temperature, humidity);

        msleep(500);
    }
    device->close();
    device->deleteLater();
}
